package mylab.starters.mybatis.handler;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import mylab.starters.mybatis.utils.MpUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 逗号分隔的字符串转换成列表
 * 列表类型仅支持基本数据类型与字符串类型
 */
@MappedJdbcTypes(value = JdbcType.VARCHAR, includeNullJdbcType = true)
public class CommaToListTypeHandler<T> extends BaseTypeHandler<List<T>> {

    static final String COMMA = ",";

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        ps.setObject(i, Joiner.on(getSplliter()).skipNulls().join(parameter).trim());
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return toList(rs.getString(columnName));
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return toList(rs.getString(columnIndex));
    }

    @Override
    public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return toList(cs.getString(columnIndex));
    }

    @SuppressWarnings("unchecked")
    List<T> toList(String text) {
        List<String> strList = Splitter.on(getSplliter()).omitEmptyStrings().trimResults().splitToList(text);
        return strList.stream().map(str -> (T) str).collect(Collectors.toList());
    }


    public String getSplliter() {
        return COMMA;
    }

    public static boolean isSplitterField(Class<?> entityClass, String column) {
        TableFieldInfo fieldInfo = MpUtils.getFieldInfoByColumn(entityClass, column);
        Assert.notNull(fieldInfo, "找不到字段信息:" + column);
        return fieldInfo.getTypeHandler() != null && CommaToListTypeHandler.class.isAssignableFrom(fieldInfo.getTypeHandler());
    }

}
